import os
import shutil
from PIL import Image
from paddleocr import PaddleOCR

import config
from base.ocr_base_tool import crop_and_save_image, formating_recognized_texts, extract_info, move_file


class Cover:
    def __init__(self, output_path=""):
        self._address = ""
        self._registration_number = ""
        self._output_path = output_path
        self._whole_strings_in_one_page = ""
        self._info_list_in_one_page = None
        self._paddle_ocr = PaddleOCR(use_angle_cls=True, lang="ch", max_text_length=64)

    @property
    def address(self):
        return self._address

    @address.setter
    def address(self, value):
        self._address = value

    @property
    def registration_number(self):
        return self._registration_number

    @registration_number.setter
    def registration_number(self, value):
        self._registration_number = value

    def recognize_cover(self, image_path):
        # self.recognize_registration_number_on_fixed_location(image_path)
        # if self._address == "":
        #     self.recognize_address_on_fixed_location(image_path)

        self.recognize_registration_number_on_most_likely_location(image_path)
        self.recognize_address_on_most_likely_location(image_path)
        self._registration_number.replace(r'登记字号：', r'')

    def recognize_cover_from_whole_page(self, image_path):
        # 使用paddleocr识别图像中的文本
        result = self._paddle_ocr.ocr(image_path, det=True, rec=True)

        #  ---   打印结果
        for idx in range(len(result)):
            res = result[idx]
            if res is None:
                continue
        ocr_result_pages_unit = result
        recognized_line_list_in_one_page = ocr_result_pages_unit[0]

        # 规范化解析文字
        (self._whole_strings_in_one_page, self._info_list_in_one_page) = formating_recognized_texts(
            recognized_line_list_in_one_page)

        print(self._whole_strings_in_one_page)

        self._registration_number = extract_info('登记字号(.*)', self._whole_strings_in_one_page, [':', '：'])
        self._address = extract_info('坐落(.*)', self._whole_strings_in_one_page, [':', '：'])

        if self._registration_number.strip() != "" and self._address.strip() != "":
            # 处理结束后将已经处理成功的输入文件转移至指定目录
            move_file(image_path, self._output_path + r'/finished_cover')
            print(f'通过识别整页得到的登记字号：{self._registration_number}')
            print(f'通过识别整页得到的 坐落：{self._address}')
        else:
            # 处理结束后将已经处理成功的输入文件转移至指定目录
            print("通过整页识别失败")
            move_file(image_path, self._output_path + r'/problem_cover')

    def recognize_registration_number_on_fixed_location(self, image_path):
        # 先截取图片再识别
        # 一定要有一定的扩展，否则会识别不出来的

        coordinate_on_image = [1000, 148, 1480, 191]  # 图片大小为：1743 * 2330

        cropped_image_path = f'{os.path.splitext(image_path)[0]}_cropped_registration' + os.path.splitext(image_path)[1]

        # 截取指定位置
        crop_and_save_image(image_path, coordinate_on_image, cropped_image_path)

        # 使用PaddleOCR识别图片中的文字
        result = self._paddle_ocr.ocr(cropped_image_path, cls=True)
        # 假设水印位于左上角，取识别结果的第一个元素
        if result and len(result) > 0 and result[0]:
            for recognized_content_list in result[0]:
                self._registration_number = self._registration_number + recognized_content_list[1][0]
            if '登' in self._registration_number:
                if len(self._registration_number) == 15:
                    move_file(cropped_image_path, self._output_path + r'/finished_cover')
                    print(f"{image_path}在固定位置上识别出的登记字号：{self._registration_number}")
                    return

        print(f"{image_path}的页面大小是非常规的。在固定位置上无法识别出登记字号。改用整页识别：")
        # 整页识别#######################################################################################
        self.recognize_cover_from_whole_page(image_path)
        move_file(cropped_image_path, self._output_path + r'/problem_cover')

    def recognize_registration_number_on_most_likely_location(self, image_path):
        # 先截取图片再识别
        # 一定要有一定的扩展，把最有可能的区域计算出来
        image = Image.open(image_path)
        left_ratio = 800 / 1743
        right_ratio = 1600 / 1743
        top_ratio = 50 / 2330
        bottom_ratio = 350 / 2330

        left = (int)(left_ratio * image.width)
        right = (int)(right_ratio * image.width)
        top = (int)(top_ratio * image.height)
        bottom = (int)(bottom_ratio * image.height)
        image.close()

        coordinate_on_image = [left, top, right, bottom]  # 图片大小为：1743 * 2330

        cropped_image_path = f'{os.path.splitext(image_path)[0]}_cropped_most_likely_registration' + \
                             os.path.splitext(image_path)[1]

        # 截取指定位置
        crop_and_save_image(image_path, coordinate_on_image, cropped_image_path)

        # 使用paddleocr识别图像中的文本
        result = self._paddle_ocr.ocr(cropped_image_path, det=True, rec=True)

        #  ---   打印结果
        for idx in range(len(result)):
            res = result[idx]
            if res is None:
                continue
        ocr_result_pages_unit = result
        recognized_line_list_in_one_page = ocr_result_pages_unit[0]

        # 规范化解析文字
        (self._whole_strings_in_one_page, self._info_list_in_one_page) = formating_recognized_texts(
            recognized_line_list_in_one_page)

        config.print_console_and_write_log_without_time(f"解释出的登记字号相关段落为：" + self._whole_strings_in_one_page)

        self._registration_number = extract_info('登记字号(.*)', self._whole_strings_in_one_page, [':', '：'])

        if self._registration_number.strip() != "":
            # 处理结束后将已经处理成功的输入文件转移至指定目录
            move_file(cropped_image_path, self._output_path + r'/finished_cover')
            config.print_console_and_write_log_without_time(f'通过识别整页中最有可能出现登记字号区域，识别得到的登记字号：{self._registration_number}')
        else:
            # 将已输入文件转移至指定目录
            config.print_console_and_write_log_without_time("通过识别整页中最有可能出现登记字号区域识别登记字时失败！请检查封面尺寸是否为标准大小或扫描件分辨率过低。")
            move_file(image_path, self._output_path + r'/problem_cover')
            move_file(cropped_image_path, self._output_path + r'/problem_cover')

    def recognize_address_on_fixed_location(self, image_path):
        """
        在固定位置上识别位置信息
        :param image_path:
        :return:
        """
        # 先截取图片再识别
        # 一定要有一定的扩展，否则会识别不出来的
        coordinate_on_image = [479, 792, 1472, 865]  # 图片大小为：1743 * 2330

        cropped_image_path = f'{os.path.splitext(image_path)[0]}_cropped_address' + os.path.splitext(image_path)[1]

        # 截取指定位置
        crop_and_save_image(image_path, coordinate_on_image, cropped_image_path)

        # 使用PaddleOCR识别图片中的文字
        result = self._paddle_ocr.ocr(cropped_image_path, cls=True)
        # 假设水印位于左上角，取识别结果的第一个元素
        if result and len(result) > 0 and result[0]:
            for recognized_content_list in result[0]:
                self._address = self._address + recognized_content_list[1][0]
            if '州' in self._address:
                # 处理结束后将已经处理成功的输入文件转移至指定目录
                move_file(image_path, self._output_path + r'/finished_cover')
                move_file(cropped_image_path, self._output_path + r'/finished_cover')
                print(f"{image_path}在固定位置上识别出的坐落：{self._address}")
                return

        print(f"{image_path}的页面大小是非常规的。在固定位置上无法识别出“坐落”。改用整页识别：")
        # 整页识别#######################################################################################
        self.recognize_cover_from_whole_page(image_path)
        move_file(cropped_image_path, self._output_path + r'/problem_cover')

    def recognize_address_on_most_likely_location(self, image_path):
        """
        在最有可能的区域位置上识别座落信息
        :param image_path:
        :return:
        """
        # 先截取图片再识别
        # 一定要有一定的扩展，把最有可能的区域计算出来
        image = Image.open(image_path)
        left_ratio = 280 / 1743
        right_ratio = 1550 / 1743
        top_ratio = 700 / 2330
        bottom_ratio = 1000 / 2330

        left = (int)(left_ratio * image.width)
        right = (int)(right_ratio * image.width)
        top = (int)(top_ratio * image.height)
        bottom = (int)(bottom_ratio * image.height)
        image.close()

        coordinate_on_image = [left, top, right, bottom]  # 图片大小为：1743 * 2330

        cropped_image_path = f'{os.path.splitext(image_path)[0]}_cropped_most_likely_address' + \
                             os.path.splitext(image_path)[1]

        # 截取指定位置
        crop_and_save_image(image_path, coordinate_on_image, cropped_image_path)

        # 使用paddleocr识别图像中的文本
        result = self._paddle_ocr.ocr(cropped_image_path, det=True, rec=True)

        #  ---   打印结果
        for idx in range(len(result)):
            res = result[idx]
            if res is None:
                continue

        ocr_result_pages_unit = result
        recognized_line_list_in_one_page = ocr_result_pages_unit[0]

        # 规范化解析文字
        (self._whole_strings_in_one_page, self._info_list_in_one_page) = formating_recognized_texts(
            recognized_line_list_in_one_page)

        config.print_console_and_write_log_without_time(f"解释出的坐落相关段落为：" + self._whole_strings_in_one_page)

        self._address = extract_info('坐*落(.*)', self._whole_strings_in_one_page, [':', '：'])

        if self._address.strip() != "":
            # 处理结束后将已经处理成功的输入文件转移至指定目录
            move_file(image_path, self._output_path + r'/finished_cover')
            move_file(cropped_image_path, self._output_path + r'/finished_cover')
            config.print_console_and_write_log_without_time(f'通过识别整页中最有可能出现坐落的区域，识别得到的坐落：{self._address}')
        else:
            # 处理结束后将已经处理成功的输入文件转移至指定目录
            config.print_console_and_write_log_without_time("通过识别整页中最有可能出现坐落的区域，识别失败")
            move_file(image_path, self._output_path + r'/problem_cover')
            move_file(cropped_image_path, self._output_path + r'/problem_cover')
